#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "fs_fat.h"
#include "fs_config.h"

//#define DEBUG

extern unsigned long offset_sectores_de_datos;

void imprimir_campo(unsigned char * buff, int largo)
{
	int i;
	for (i = 0 ; i<largo;i++)
	{
		//putchar(buff[i]);
		printf("%X", *(buff +i));
	}
}
void llenar_desde_cluster(char *v_FS_information_sector, char *cluster, unsigned long long comienzo , unsigned long long largo)
{
	//printf("\nlleno desde %d hasta %d",comienzo,(largo+comienzo));
	unsigned long long i;
	for (i = comienzo; i<(largo + comienzo);i++)
	{
		//putchar(cluster[i]);
		v_FS_information_sector[i-comienzo] = cluster[i];
	}
}


void byte_a_sector(unsigned long long byteIngreso, unsigned long *sector, unsigned long *cluster, unsigned long *byte)
{
	*cluster = (unsigned long)(byteIngreso / (unsigned long long) SIZE_SECTOR / (unsigned long long) SECTOR_PER_CLUSTER);
	*sector = (unsigned long)(byteIngreso / SIZE_SECTOR);
	*byte = byteIngreso - (*cluster * SIZE_SECTOR * SECTOR_PER_CLUSTER);
	*sector = (*byte / 512);
	*byte = byteIngreso - (*cluster * SIZE_SECTOR * SECTOR_PER_CLUSTER)- (*sector * SIZE_SECTOR);
}

unsigned long largo_tabla_tabla_FAT_bytes(union boot_sector  v_boot_sector)
{
	return (v_boot_sector.valores.value_sectors_per_fat_table * SIZE_SECTOR);
}

unsigned int largo_tabla_tabla_FAT_entero(union boot_sector  v_boot_sector)
{
	return (v_boot_sector.valores.value_sectors_per_fat_table * SIZE_SECTOR / sizeof(int));
}

unsigned int * llenar_Tabla_FAT (union boot_sector  v_boot_sector, FILE *fp)
{
  unsigned long long posicion_arranque_tabla_FAT;
  unsigned long long posicion_final_tabla_FAT;
  unsigned int *entrada_FAT;
  posicion_arranque_tabla_FAT = (unsigned long long)(v_boot_sector.valores.value_reserved_sector_count * SIZE_SECTOR);


  unsigned long sectorFatInicio,clusterFatInicio, byteFatInicio,sectorFatFinal,clusterFatFinal, byteFatFinal;
  byte_a_sector(posicion_arranque_tabla_FAT,&sectorFatInicio,&clusterFatInicio,&byteFatInicio);
  posicion_final_tabla_FAT = posicion_arranque_tabla_FAT+(v_boot_sector.valores.value_sectors_per_fat_table * SIZE_SECTOR);
  byte_a_sector(posicion_final_tabla_FAT,&sectorFatFinal,&clusterFatFinal,&byteFatFinal);

  #ifdef DEBUG
  printf ("\nPosición sector de arranque FAT: %d", posicion_arranque_tabla_FAT);
  printf ("\nPosición cluster de arranque FAT: %u", clusterFatInicio);
  printf ("\nPosición del sector %d", sectorFatInicio);
  printf ("\nPosición del byte %d\n", byteFatInicio);
  printf("\nFinal de tabla FAT: %d", v_boot_sector.valores.value_sectors_per_fat_table / SECTOR_PER_CLUSTER);
  printf ("\nPosición cluster de final FAT: %u", clusterFatFinal);
  printf ("\nPosición del sector %d", sectorFatFinal);
  printf ("\nPosición del byte %d\n", byteFatFinal);
  printf("Largo del malloc para la tabla FAT32: %d",(v_boot_sector.valores.value_sectors_per_fat_table * SIZE_SECTOR));
  #endif

  //primero creo un vector de la cantidad de entradas necesarias
  entrada_FAT = (int *)malloc(largo_tabla_tabla_FAT_bytes(v_boot_sector));
  //lleno el vector con las entradas fat U.U
  unsigned char *desplazador_FAT;
  desplazador_FAT = entrada_FAT;
  int byteInicio, byteFin;
  unsigned long long acum;
  acum=0;
  char *bloque_cluster;
  bloque_cluster = (char *)malloc( SECTOR_PER_CLUSTER*SIZE_SECTOR*sizeof(char));
  unsigned int i;
  for(i=clusterFatInicio; i<=clusterFatFinal;i++)
  {
	  bloque_cluster=leer_un_cluster(i, fp);
	  if (clusterFatInicio == i)
		  {
			  byteInicio = sectorFatInicio * SIZE_SECTOR + byteFatInicio;
			  byteFin = SECTOR_PER_CLUSTER*SIZE_SECTOR*sizeof(char)-byteInicio;
		  }
	  else if (clusterFatFinal==i)
		  {
			  byteInicio=0;
			  byteFin = sectorFatFinal * SIZE_SECTOR + byteFatFinal;
		  }
	  else
		  {
			  byteInicio=0;
			  byteFin = SECTOR_PER_CLUSTER*SIZE_SECTOR*sizeof(char);
		  }
	  acum = acum + (byteFin-byteInicio);
	  llenar_desde_cluster(desplazador_FAT, bloque_cluster, byteInicio ,byteFin);
	  desplazador_FAT = desplazador_FAT+(byteFin-byteInicio);
  }
  free (bloque_cluster);
  printf("\nFAT Leída :)");
  return entrada_FAT;
}

unsigned long clusters_libres_en_FAT(int* tabla_FAT, unsigned long largo_tabla_FAT)
{
	unsigned long acum;
	acum = 0;
	int i ;
	for(i = 0 ; i<largo_tabla_FAT;i++)
	{
		if (tabla_FAT[i]==CLUSTER_LIBRE)
			acum = acum + 1;
	}
	return acum;

}

unsigned int proximo_cluster_en_cadena(const int* tabla_FAT, unsigned int cluster)
{
	return tabla_FAT[cluster];
}

unsigned long offset_sectores_para_datos(union boot_sector v_boot_sector)
{
	return (v_boot_sector.valores.value_reserved_sector_count + 2 * v_boot_sector.valores.value_sectors_per_fat_table)/SECTOR_PER_CLUSTER;
}

//void lectura_de_cache
/*
char * traer_cadena_de_clusters(int * tablaFAT, unsigned int entrada_inicial)
{
	char * temp;
	//si la entrada está marcada como última, devuelvo la entrada
	if ((tablaFAT[entrada_inicial] - CLUSTER_OCUPADO) >= 0)
		sprintf(temp,"%d",entrada_inicial);
		return temp;
	//si no, sigo iterando
	temp = (char *)entrada_inicial;
	temp = strcat(temp ,",");

	return strcat(temp ,traer_cadena_de_clusters(tablaFAT,(unsigned int) tablaFAT[entrada_inicial] ));
}

void traer_bloque_de_entrada(unsigned int sector_absoluto, char* cadena_de_clusters,fp)
{

}

void traer_entrada_de_directorio(int * tablaFAT, char * path_carpeta, char * buffer, unsigned int *largo_de_bloque)
{
	char *bloque_cluster;
	char *cadena_de_clusters;
	//traigo la entrada del raíz
	//recorro la tabla FAT para ver cuantos clusters ocupa.
	cadena_de_clusters = traer_cadena_de_clusters(tablaFAT,2);
	traer_bloque_de_entrada(2 + offset_sectores_de_datos,cadena_de_clusters,fp);


	//si no es el raíz, busco dentro de la entrada cual es la primera
	//carpeta y empiezo a iterar hasta el final
	if (!strcmp("/",path_carpeta))
	{
		//si es el raíz, leo la primer entrada de directorio

	}

}*/
